home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / ppt100.zip / LIST2.C < prev    next >
C/C++ Source or Header  |  1993-05-01  |  21KB  |  863 lines

  1. /*
  2.  *  File Browse Utility, version 1.4
  3.  *
  4.  *  (c) 1992 Barry Nance
  5.  *
  6.  *  distributed through
  7.  *  BYTE Magazine's Software Corner
  8. */
  9.  
  10. // Original program by Mr. Nance was all incorporated in one file: LIST.C.
  11. // I split it up in order to demonstrate some PPT functionality.
  12. // No substantive changes.   This is the 2nd of two source modules,
  13. // LIST1.C and LIST2.c.  There is also a header file, LIST.H.
  14. // Gary L. Levine, Feb/1993.
  15.  
  16. #include <stdio.h>
  17. #include <dos.h>
  18. #include <dir.h>
  19. #include <bios.h>
  20. #include <fcntl.h>
  21. #include <conio.h>
  22. #include <io.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include <alloc.h>
  26. #include <process.h>
  27. #include <ctype.h>
  28. #include <share.h>
  29. #include <errno.h>
  30. #include <list.h>
  31.  
  32.  
  33. /************************************/
  34.  
  35. extern  char  *fileprompt;
  36. extern  char  *inv_arg;
  37. extern  char  *notfound;
  38. extern  char  *emptyfile;
  39. extern  char  *noaccess;
  40. extern  char  *presskey;
  41.  
  42. extern  *help[];
  43.  
  44. extern  unsigned char string[];
  45. extern  char  string1[];
  46.  
  47. extern  char  search_arg[];
  48. extern  int   search_flag;
  49. extern  int   ignore_case;
  50. extern  int   spos;
  51.  
  52. extern  long  line_number;
  53. extern  long  linenum_save;
  54.  
  55. extern  unsigned char CharCode;
  56. extern  unsigned char ScanCode;
  57.  
  58. extern  int   xesc;
  59. extern  int   eof_flag;
  60. extern  int   start_of_file;
  61. extern  int   line_end_char;
  62. extern  int   hex_mode;
  63. extern  int   wrap_mode;
  64.  
  65. extern  int   start_save;
  66. extern  int   eof_save;
  67. extern  int   fbufblock_save;
  68. extern  int   fbufndx_save;
  69.  
  70. extern  unsigned    top, left, bottom, right, screen_width, screen_height;
  71. extern  int         left_relative_pos;
  72.  
  73. extern  struct ftime ftimestruc;
  74. extern  struct ffblk findblock;
  75.  
  76. extern  char  filename[];
  77. extern  char  drive[];
  78. extern  char  path[];
  79. extern  char  name[];
  80. extern  char  ext[];
  81.  
  82. extern  int   count;
  83. extern  int   flag;
  84. extern  int   file_num;
  85. extern  int   current_row;
  86. extern  int   file_is_empty;
  87.  
  88. extern  int   screen_rcds;
  89. extern  int   screen_lines_hold;
  90. extern  int   screen_lines;
  91. extern  int   lines_read;
  92. extern  int   rcds_read;
  93. extern  int   lines_displayed;
  94.  
  95. extern  unsigned    i, j, k;
  96.  
  97. extern  int   fh;
  98. extern  long  filesize;
  99. extern  long  curr_filepos;
  100. extern  long  temp_long;
  101. extern  unsigned    num_blocks;
  102. extern  int   fbufndx;
  103. extern  int   fbufbytes;
  104. extern  unsigned    fbufblock;
  105.  
  106. extern  char  *filelist_ptr;
  107. extern  char  *list_ptr;
  108. extern  char  *file_buff_ptr;
  109. extern  char  *screen_save_ptr;
  110. extern  char  *dos_screen_save_ptr;
  111.  
  112. extern  char  line_save[160];
  113.  
  114. extern  unsigned char low_inten;
  115. extern  unsigned char high_inten;
  116. extern  unsigned char found_attr;
  117.  
  118. extern  struct  csavetype   cursor_data;
  119. extern  struct  csavetype   my_cpos;
  120. extern  struct  csavetype   dos_cpos;
  121.  
  122. extern  union   REGS regs;
  123.  
  124. extern  int skip[];         /* increment to rightmost occurance of ch */
  125. extern  int cmap[];         /* upper to lowercase character map */
  126.  
  127.  
  128. /************************************/
  129.  
  130. void    fill_window(void)
  131.         {
  132.         textattr(low_inten);
  133.         window(left+1, top+1, right-1, bottom-1);
  134.         clrscr();
  135.         window(1, 1, 80, 25);
  136.  
  137.         current_row = top + 1;
  138.         screen_rcds = 0;
  139.         screen_lines= 0;
  140.  
  141.         while (screen_lines < bottom - top - 1)
  142.             {
  143.             if (fgetrecord(string, STR_SIZE) == -1)
  144.                 break;
  145.             screen_rcds++;
  146.             textattr(low_inten);
  147.             if ( search_flag == 2
  148.               && (search(search_arg, strlen(search_arg),
  149.                           string, strlen(string)) != -1) )
  150.                 textattr(found_attr);
  151.             if (hex_mode)
  152.                 display_hex();
  153.             else
  154.                 display_line();
  155.             screen_lines += lines_displayed;
  156.             }
  157.         }
  158.  
  159. /************************************/
  160.  
  161. void    display_line(void)
  162.         {
  163.         int w, index;
  164.         char s[81];
  165.  
  166.         w = 0;
  167.         lines_displayed = 0;
  168.         index = left_relative_pos;
  169.  
  170.         do  {
  171.             window(left + 1, current_row, right - 1, current_row);
  172.             clrscr();
  173.             window(1, 1, 80, 25);
  174.             gotoxy(left + 1, current_row);
  175.             strncpy(s, &string[index], screen_width);
  176.             s[screen_width] = '\0';
  177.             cputs(s);
  178.             current_row++;
  179.             lines_displayed++;
  180.             if (strlen(&string[index]) < screen_width + 1)
  181.                 return;
  182.             index += screen_width;
  183.             w += screen_width;
  184.             }
  185.         while (wrap_mode && current_row < bottom);
  186.         }
  187.  
  188. /************************************/
  189.  
  190. void    show_line_num(void)
  191.         {
  192.         if (hex_mode || line_number == -1L)
  193.             strcpy(string1, "     ");
  194.         else
  195.             sprintf(string1, "%5ld", line_number);
  196.  
  197.         textattr(high_inten);
  198.         gotoxy(7, 25);
  199.         cputs(string1);
  200.         gotoxy(80, 25);
  201.         }
  202.  
  203. /************************************/
  204.  
  205. void    display_hex(void)
  206.         {
  207.         int i, column_shift;
  208.         unsigned char ch;
  209.  
  210.         column_shift = 10;
  211.         if ( search_flag == 2
  212.           && (search(search_arg, strlen(search_arg),
  213.                       string, strlen(string)) != -1) )
  214.             textattr(found_attr);
  215.         else
  216.             textattr(low_inten);
  217.  
  218.         gotoxy(left + 2, current_row);
  219.         cprintf("%6.6lX ", curr_filepos);
  220.         lines_displayed = 1;
  221.  
  222.         for (i=0; i<16; i++)
  223.             {
  224.             if (curr_filepos + i == filesize)
  225.                 break;
  226.             ch = string[i];
  227.             gotoxy(left + column_shift + (i * 3), current_row);
  228.             cprintf("%2.2X ", (int) ch);
  229.             if (i == 7)
  230.                 {
  231.                 cprintf("- ");
  232.                 column_shift = 12;
  233.                 }
  234.             gotoxy(left + 61 + i, current_row);
  235.             if (   ch == 0  || ch == BELL
  236.                 || ch == BS || ch == TAB
  237.                 || ch == LINEFEED || ch == CR  )
  238.                 ch = '.';
  239.             cprintf("%c", ch);
  240.             }
  241.  
  242.         current_row++;
  243.         textattr(low_inten);
  244.         }
  245.  
  246. /************************************/
  247.  
  248. int     fgetbyte(void)
  249.         {
  250.         eof_flag = FALSE;
  251.         start_of_file = FALSE;
  252. fgetbyte01:
  253.         if (fbufblock == (num_blocks - 1) && fbufndx == fbufbytes)
  254.             return -1;
  255.  
  256.         if (fbufndx < fbufbytes)
  257.             return (int) file_buff_ptr[fbufndx++];
  258.  
  259.         fbufblock++;
  260.         fbufndx = 0;
  261.         lseek(fh, ((long) fbufblock) * BUFSIZEL, SEEK_SET);
  262.         fbufbytes = read(fh, file_buff_ptr, BUFSIZE);
  263.         goto fgetbyte01;
  264.         }
  265.  
  266. /************************************/
  267.  
  268. int     fgetline(unsigned char buff[], int max_chars)
  269.         {
  270.         int  ch, i;
  271.  
  272.         if (hex_mode || !wrap_mode)
  273.             return fgetrecord(buff, max_chars);
  274.  
  275.         memset(buff, 0, max_chars);
  276.         i = 0;
  277.  
  278.         while (i < screen_width)
  279.             {
  280.             if ( (ch = fgetbyte()) == -1)
  281.                 {
  282.                 if (i == 0)
  283.                     {
  284.                     eof_flag = TRUE;
  285.                     return -1;
  286.                     }
  287.                 break;
  288.                 }
  289.             if (ch == line_end_char || ch == 0)
  290.                 break;
  291.             if (ch == CR || ch == LINEFEED || ch == BS)
  292.                 continue;
  293.             if (ch == TAB)
  294.                 {
  295.                 do
  296.                     buff[i++] = SPACE;
  297.                 while ( (i % 4) != 0 );
  298.                 continue;
  299.                 }
  300.             if (ch == BELL)
  301.                 ch = SPACE;
  302.             buff[i++] = (unsigned char) ch;
  303.             }
  304.  
  305.         lines_read++;
  306.         return 0;
  307.         }
  308.  
  309. /************************************/
  310.  
  311. int     fgetrecord(unsigned char buff[], int max_chars)
  312.         {
  313.         int    i, c, rc;
  314.  
  315.         memset(buff, 0, max_chars);
  316.         if (hex_mode)
  317.             {
  318.             curr_filepos = ( ((long) fbufblock) * BUFSIZEL) + fbufndx;
  319.             for (i=0; i<16; i++)
  320.                 {
  321.                 if ( (c = fgetbyte()) == -1 )
  322.                     if (i == 0 || search_flag != 0)
  323.                         {
  324.                         eof_flag = TRUE;
  325.                         rc = -1;
  326.                         goto fgs_exit;
  327.                         }
  328.                     else
  329.                         {
  330.                         lines_read++;
  331.                         rc = 0;
  332.                         goto fgs_exit;
  333.                         }
  334.                 buff[i] = (unsigned char) c;
  335.                 }
  336.             lines_read++;
  337.             rc = 0;
  338.             goto fgs_exit;
  339.             }
  340.  
  341.         i = 0;
  342. fgs1:   if (i == max_chars - 1)
  343.             {
  344.             if (wrap_mode)
  345.                 {
  346.                 c = (i + screen_width-1) / screen_width;
  347.                 if (c == 0) c = 1;
  348.                 lines_read += c;
  349.                 }
  350.             else
  351.                 {
  352.                 lines_read++;
  353.                 }
  354.             rc = 0;
  355.             goto fgs_exit;
  356.             }
  357.  
  358.         if ( (c = fgetbyte()) == -1 )
  359.             {
  360.             if (i == 0)
  361.                 {
  362.                 eof_flag = TRUE;
  363.                 rc = -1;
  364.                 goto fgs_exit;
  365.                 }
  366.             if (wrap_mode)
  367.                 {
  368.                 c = (i + screen_width-1) / screen_width;
  369.                 if (c == 0) c = 1;
  370.                 lines_read += c;
  371.                 }
  372.             else
  373.                 lines_read++;
  374.             rc = 0;
  375.             goto fgs_exit;
  376.             }
  377.  
  378.         if (c == line_end_char || c == 0)
  379.             {
  380.             if (wrap_mode)
  381.                 {
  382.                 c = (i + screen_width-1) / screen_width;
  383.                 if (c == 0) c = 1;
  384.                 lines_read += c;
  385.                 }
  386.             else
  387.                 lines_read++;
  388.             rc = 0;
  389.             goto fgs_exit;
  390.             }
  391.  
  392.         if (c == CR || c == LINEFEED)
  393.             goto fgs1;
  394.         if (c == BS && i == 0)
  395.             goto fgs1;
  396.  
  397.         if (c == TAB)
  398.             {
  399.             do
  400.                 buff[i++] = SPACE;
  401.             while ( (i % 4) != 0 );
  402.             goto fgs1;
  403.             }
  404.  
  405.         if (c == BELL)
  406.             c = SPACE;
  407.  
  408.         buff[i++] = (unsigned char) c;
  409.         goto fgs1;
  410.  
  411.  
  412. fgs_exit:
  413.         if (rc != -1)
  414.             rcds_read++;
  415.  
  416.         return rc;
  417.         }
  418.  
  419. /************************************/
  420.  
  421. int     fprevbyte(void)
  422.         {
  423.         eof_flag = FALSE;
  424.         start_of_file = FALSE;
  425. sprev01:
  426.         if (fbufblock == 0 && fbufndx <= 0)
  427.             return -1;
  428.  
  429.         if (fbufndx > 0)
  430.             return (int) file_buff_ptr[--fbufndx];
  431.  
  432.         fbufblock--;
  433.         lseek(fh, ((long) fbufblock) * BUFSIZEL, SEEK_SET);
  434.         fbufbytes = read(fh, file_buff_ptr, BUFSIZE);
  435.         fbufndx = fbufbytes;
  436.         goto sprev01;
  437.         }
  438.  
  439. /************************************/
  440.  
  441. int     fprevline(void)
  442.         {
  443.         int  ch, i, j;
  444.  
  445.         if (hex_mode || !wrap_mode)
  446.             return fprevrecord();
  447.  
  448.         if ( (ch = fprevbyte()) == -1)
  449.             {
  450.             start_of_file = TRUE;
  451.             return -1;
  452.             }
  453.  
  454.         i = 1;
  455.         if (ch == line_end_char || ch == 0)
  456.             ch = fprevbyte();
  457.  
  458.         while (ch != line_end_char && ch != 0 && ch != -1)
  459.             {
  460.             ch = fprevbyte();
  461.             if (ch == CR || ch == LINEFEED || ch == BS)
  462.                 continue;
  463.             i++;
  464.             }
  465.  
  466.         j = 0;
  467.         while (i > screen_width || j % (screen_width + 1) != 0)
  468.             {
  469.             ch = fgetbyte();
  470.             i--;
  471.             j++;
  472.             }
  473.  
  474.         lines_read++;
  475.         return 0;
  476.         }
  477.  
  478. /************************************/
  479.  
  480. int     fprevrecord(void)
  481.         {
  482.         int     ch, slen, rc;
  483.  
  484.         if (hex_mode)
  485.             {
  486.             if (fprevbyte() == -1)
  487.                 {
  488.                 start_of_file = TRUE;
  489.                 rc = -1;
  490.                 goto g1l_exit;
  491.                 }
  492.             while ( (fbufndx % 16) != 0 )
  493.                 {
  494.                 if (fprevbyte() == -1)
  495.                     break;
  496.                 }
  497.             lines_read++;
  498.             rc = 0;
  499.             goto g1l_exit;
  500.             }
  501.  
  502.         if ( (ch = fprevbyte()) == -1)
  503.             {
  504.             start_of_file = TRUE;
  505.             rc = -1;
  506.             goto g1l_exit;
  507.             }
  508.  
  509.         slen = 1;
  510.         if (ch == line_end_char || ch == 0)
  511.             ch = fprevbyte();
  512.  
  513.         while (ch != line_end_char && ch != 0 && ch != -1)
  514.             {
  515.             slen++;
  516.             ch = fprevbyte();
  517.             }
  518.  
  519.         if (ch != -1)
  520.             {
  521.             slen--;
  522.             ch = fgetbyte();
  523.             }
  524.  
  525.         if (wrap_mode)
  526.             {
  527.             ch = (slen + screen_width-1) / screen_width;
  528.             if (ch == 0) ch = 1;
  529.             lines_read += ch;
  530.             }
  531.         else
  532.             lines_read++;
  533.  
  534.         rc = 0;
  535.  
  536. g1l_exit:
  537.         if (rc != -1)
  538.             rcds_read++;
  539.  
  540.         return rc;
  541.         }
  542.  
  543. /************************************/
  544.  
  545. void    gohome(void)
  546.         {
  547.         if (xesc) goto restore_the_screen;
  548.  
  549.         textattr(high_inten);
  550.         gotoxy(1, 25);
  551.         cputs(presskey);
  552.         getkey();
  553.  
  554. restore_the_screen:
  555.         puttext(1, 1, 80, 25, screen_save_ptr);
  556.         restore_cursor(&cursor_data);
  557.  
  558.         free(file_buff_ptr);
  559.         free(screen_save_ptr);
  560.         free(dos_screen_save_ptr);
  561.         free(filelist_ptr);
  562.  
  563.         exit(0);
  564.         }
  565.  
  566. /************************************/
  567.  
  568.  
  569. void    save_cursor(struct csavetype *csave)
  570.         {
  571.         _AH = 3;
  572.         _BH = 0;
  573.         geninterrupt(0x10);
  574.         csave->curloc  = _DX;
  575.         csave->curmode = _CX;
  576.         }
  577.  
  578.  
  579. void    restore_cursor(struct csavetype *csave)
  580.         {
  581.         _DX = csave->curloc;
  582.         _AH = 2;
  583.         _BH = 0;
  584.         geninterrupt(0x10);
  585.  
  586.         _CX = csave->curmode;
  587.         _AH = 1;
  588.         geninterrupt(0x10);
  589.         }
  590.  
  591.  
  592.  
  593. int     kbdstring(char buff[], int max_chars)
  594.         {
  595.         int             ft, i, j, insert_mode, ctype, res;
  596.         unsigned char   row, col, trow, tcol;
  597.         unsigned int    cblock;
  598.  
  599.         ft = TRUE;
  600.         i = j = insert_mode = 0;
  601.         if (get_video_mode() == 7)
  602.             cblock = 0x000D;
  603.         else
  604.             cblock = 0x0007;
  605.  
  606.         _AH = 3;
  607.         _BH = 0;
  608.         geninterrupt(0x10);
  609.         ctype = _CX;
  610.         col = wherex();
  611.         row = wherey();
  612.  
  613.         cprintf("%-*s", max_chars-1, buff);
  614.         gotoxy(col, row);
  615.  
  616. ks1:    getkey();
  617.         tcol = wherex();
  618.         trow = wherey();
  619.  
  620.         if (CharCode == ESC)
  621.             {
  622.             buff[0] = '\0';
  623.             res = 0;
  624.             goto kbdstring_exit;
  625.             }
  626.  
  627.         if (CharCode == 0)
  628.             {
  629.             if (ScanCode == INSKEY)
  630.                 {
  631.                 if (insert_mode)
  632.                     {
  633.                     insert_mode = FALSE;
  634.                     _CX = ctype;
  635.                     _AH = 1;
  636.                     geninterrupt(0x10);
  637.                     }
  638.                 else
  639.                     {
  640.                     insert_mode = TRUE;
  641.                     _CX = cblock;
  642.                     _AH = 1;
  643.                     geninterrupt(0x10);
  644.                     }
  645.                 }
  646.             else
  647.             if (ScanCode == HOMEKEY)
  648.                 {
  649.                 i = 0;
  650.                 gotoxy(col, row);
  651.                 }
  652.             else
  653.             if (ScanCode == ENDKEY)
  654.                 {
  655.                 i = strlen(buff);
  656.                 gotoxy(col+strlen(buff), row);
  657.                 }
  658.             else
  659.             if (ScanCode == DELKEY)
  660.                 {
  661.                 for (j = i; j < strlen(buff); j++)
  662.                     buff[j] = buff[j+1];
  663.                 gotoxy(col, row);
  664.                 cprintf("%-*s", max_chars-1, buff);
  665.                 gotoxy(tcol, trow);
  666.                 }
  667.             else
  668.             if (ScanCode == RIGHTKEY)
  669.                 {
  670.                 if (i < strlen(buff))
  671.                     {
  672.                     i++;
  673.                     gotoxy(tcol+1, trow);
  674.                     }
  675.                 }
  676.             else
  677.             if (ScanCode == LEFTKEY)
  678.                 {
  679.                 if (i > 0)
  680.                     {
  681.                     i--;
  682.                     gotoxy(tcol-1, trow);
  683.                     }
  684.                 }
  685.             }
  686.  
  687.         if (CharCode == 0)
  688.             goto ks1;
  689.  
  690.         if (CharCode == BS)
  691.             {
  692.             if (i > 0)
  693.                 {
  694.                 i--;
  695.                 gotoxy(tcol-1, trow);
  696.                 }
  697.             }
  698.  
  699.         if (CharCode == CR)
  700.             {
  701.             res = 0;
  702.             goto kbdstring_exit;
  703.             }
  704.  
  705.         if (CharCode < 32)
  706.             goto ks1;
  707.  
  708.         if (i == max_chars-1)
  709.             goto ks1;
  710.  
  711.         if (ft)
  712.             {
  713.             ft = FALSE;
  714.             if (i == 0 && !insert_mode)
  715.                 {
  716.                 memset(buff, 0, max_chars);
  717.                 gotoxy(col, row);
  718.                 cprintf("%-*s", max_chars-1, buff);
  719.                 gotoxy(col, row);
  720.                 }
  721.             }
  722.  
  723.         if (insert_mode)
  724.             {
  725.             for (j = strlen(buff)-1; j >= i; j--)
  726.                 if (j < max_chars-2)
  727.                     buff[j+1] = buff[j];
  728.             buff[i++] = CharCode;
  729.             _CX = ctype;
  730.             _AH = 1;
  731.             geninterrupt(0x10);
  732.             gotoxy(col, row);
  733.             cprintf("%-*s", max_chars-1, buff);
  734.             gotoxy(++tcol, trow);
  735.             _CX = cblock;
  736.             _AH = 1;
  737.             geninterrupt(0x10);
  738.             }
  739.         else
  740.             {
  741.             buff[i++] = CharCode;
  742.             cprintf("%c", CharCode);
  743.             }
  744.  
  745.         goto ks1;
  746.  
  747.  
  748. kbdstring_exit:
  749.         _CX = ctype;
  750.         _AH = 1;
  751.         geninterrupt(0x10);
  752.         return res;
  753.         }
  754.  
  755. void    getkey(void)
  756.         {
  757.         int     k;
  758.  
  759.         k        = bioskey(0);
  760.         CharCode = k & 0x00FF;
  761.         ScanCode = (k & 0xFF00) >> 8;
  762.         }
  763.  
  764. int     get_video_mode(void)
  765.         {
  766.         regs.x.ax = 0x0f00;
  767.         int86(0x10, ®s, ®s);
  768.         regs.h.ah = 0;
  769.         return regs.x.ax;
  770.         }
  771.  
  772. void    scroll_up(unsigned char numlines)
  773.         {
  774.         regs.h.ah = 6;
  775.         regs.h.al = numlines;
  776.         regs.h.ch = (unsigned char) top;
  777.         regs.h.cl = (unsigned char) left;
  778.         regs.h.dh = (unsigned char) bottom-2;
  779.         regs.h.dl = (unsigned char) right-2;
  780.         regs.h.bh = (unsigned char) low_inten;
  781.         int86(0x10, ®s, ®s);
  782.         }
  783.  
  784. void    scroll_dn(unsigned char numlines)
  785.         {
  786.         regs.h.ah = 7;
  787.         regs.h.al = numlines;
  788.         regs.h.ch = (unsigned char) top;
  789.         regs.h.cl = (unsigned char) left;
  790.         regs.h.dh = (unsigned char) bottom-2;
  791.         regs.h.dl = (unsigned char) right-2;
  792.         regs.h.bh = (unsigned char) low_inten;
  793.         int86(0x10, ®s, ®s);
  794.         }
  795.  
  796. /************************************/
  797.  
  798. void    search_setup(pat,plen,icase)
  799.                   unsigned char *pat;   /* pattern */
  800.                   int plen;             /* pattern length */
  801.                   int icase;            /* ignore case */
  802.  
  803.         {
  804.         register unsigned char *p;
  805.         register int i;
  806.  
  807.     /* initialize the skip array and character map */
  808.         for (i = 0; i < CSIZE; ++i)
  809.             {
  810.             skip[i] = plen;
  811.             cmap[i] = i;
  812.             }
  813.  
  814.     /* map upper to lowercase on case insensitive searches */
  815.         if (icase)
  816.             for (i = 'A'; i <= 'Z'; ++i)
  817.                 cmap[i] = tolower(i);
  818.     
  819.     /* compute the skip values for characters in the pattern */
  820.         for (i = plen-1, p = pat; i > 0; --i, ++p)
  821.             skip[cmap[*p]] = i;
  822.         }
  823.  
  824.  
  825. int     search(pat,plen,str,slen)
  826.                   unsigned char *pat;   /* pattern */
  827.                   int plen;             /* pattern length */
  828.                   unsigned char *str;   /* string */
  829.                   int slen;             /* string length */
  830.         {
  831.         register unsigned char *pp,*pe,*sp,*se,*sb;
  832.  
  833.     /* exit immediately if the pattern is longer than the string */
  834.         if (plen > slen)
  835.             return -1;
  836.  
  837.     /* compute the pattern and string ends */
  838.         pe = pat + plen;    
  839.         se = str + slen;
  840.  
  841.     /* compute the starting point for the first match attempt */
  842.         sb = str + plen - 1;
  843.  
  844.     /* match the pattern against the string */
  845.         do {
  846.             pp = pe - 1;
  847.             sp = sb;
  848.             while (pp >= pat && cmap[*sp] == cmap[*pp])
  849.                 {
  850.                 --sp;
  851.                 --pp;
  852.                 }
  853.             if (pp < pat)
  854.                 return (sp - str + 1);
  855.             }
  856.         while ((sb += skip[cmap[*sb]]) < se);
  857.  
  858.     /* no match found */
  859.         return -1;
  860.         }
  861.  
  862.  
  863.